 using System;
using System.Collections;
using System.Net;
using System.IO;
using System.Web.Script.Serialization;
using System.Collections.Generic;
using System.Reflection;
using Word = Microsoft.Office.Interop.Word;

namespace VirusTotalAPI
{
    
    class Program
    {
       

        static void Main(string[] args)
        {
            read_file ReadText = new read_file();
            Hashtable filenamestomd5 = new Hashtable();
            request BuildVirusTotalWebRequest = new request();
            string md5filepath, ReportFilePath;
            switch (args.Length)
            {
                case 0:
                    {
                        Console.WriteLine("NO file supplied");
                        Console.WriteLine("file should look like:");
                        Console.WriteLine("\"Md5 hash\" \"File Path\"");
                        md5filepath = "";
                        ReportFilePath = "";
                        return;
                    }
                case 1:
                    {
                        md5filepath = args[0];
                        ReportFilePath = "VirusTotalAPIReport.docx";
                        return ;
                    }
                case 2:
                    {
                        md5filepath = args[0];
                        BuildVirusTotalWebRequest.APIKey = args[1];
                        ReportFilePath = "VirusTotalAPIReport.docx";
                        break;
                    }
                case 3:
                    {
                        md5filepath = args[0];
                        BuildVirusTotalWebRequest.APIKey = args[1];
                        ReportFilePath = args[2];
                        break;
                    }
                default:
                    {
                        Console.WriteLine("NO file supplied");
                        Console.WriteLine("file should look like:");
                        Console.WriteLine("\"Md5 hash\" \"File Path\"");
                        Console.WriteLine("Expected command is VirusTotalAPI.exe <Filename for FCIV output> <Virustotal API Key> <Output filename>" );
                        md5filepath = "";
                        ReportFilePath = "";
                        return;
                        
                    }

            }

            filenamestomd5 = ReadText.md5(md5filepath);
            //int t = ReadText.md5().Count;
            Console.WriteLine("Buliding VirusTotal URL with File located: ");
            Console.WriteLine(md5filepath);
            //Console.WriteLine("File looks like: ");
            string WebRequestURLVirusTotal = BuildVirusTotalWebRequest.createhtml(filenamestomd5);
            Console.WriteLine("Finished Buliding VirusTotal URL");
            //Console.WriteLine(blah);
            //Console.WriteLine("Finished manual string :");

            Console.WriteLine("Calling Virus Total");
            WebRequest VirusTotalWebRequest = HttpWebRequest.Create(WebRequestURLVirusTotal);
            WebResponse VirusTotalWebResponse = VirusTotalWebRequest.GetResponse();
            StreamReader reader = new StreamReader(VirusTotalWebResponse.GetResponseStream());
            string urlText = reader.ReadToEnd();
            //Console.WriteLine(urlText);
            Console.WriteLine("Virus Total Call finished");

            parse_jsontxt boom = new parse_jsontxt();
            

            boom.tobeparsed(urlText);
            
            if (boom.hashkeyScanned("BeenScanned"))
            {
                boom.Scaned();
                boom.buildrootscannedobject();
            }
            if (boom.HashKeyNotScanned("NotScanned"))
            {
                boom.NotScaned();
                boom.buildrootnotscannedobject();
            }
            Console.WriteLine("Creating the report document");
            //Create a Word Doc or results from VirusTotal API
            boom.bulidworddoc(filenamestomd5, ReportFilePath);
            
            
            Console.WriteLine("Press Enter to exit program");
            Console.ReadLine();


        }

        class request
        {
            public string APIKey { get; set; }
            public request(string apikey)
            {
                this.APIKey = apikey; 
            }
            public request()
            {
                this.APIKey = "null";
            }
            public string createhtml(Hashtable hashs)
            {
                string VirusTotalAPIKey;
                //string.Equals(Key_value, this.bs, StringComparison.OrdinalIgnoreCase)
                if ( string.Equals(this.APIKey.ToString(),"null", StringComparison.OrdinalIgnoreCase))
                {
                    
                    VirusTotalAPIKey = "<Virustotal API Key>";
                }
                else
                {
                    VirusTotalAPIKey = this.APIKey.ToString();
                }

                string json_test;

                json_test = "https://www.virustotal.com/vtapi/v2/file/report?"
                     + "&apikey="
                     + VirusTotalAPIKey.ToString()
                     + "&resource=";
                foreach (string value in hashs.Keys)
                {
                    json_test += "," + value;
                }
                return (json_test);
            }
        }
        class read_file
        {

            public Hashtable md5(string filepath)
            {
                Hashtable md5hashtable = new Hashtable();
                int counter = 0;
                string line;
                

                // Read the file and display it line by line.
                System.IO.StreamReader file = new System.IO.StreamReader(filepath);
                while ((line = file.ReadLine()) != null)
                {
                    //Console.WriteLine(line.IndexOf(" "));
                    string[] tobeparsed = line.Split(' ');
                    if (tobeparsed.Length > 0)
                    {
                        string key = tobeparsed[0].Trim();
                        string val = tobeparsed[1].Trim();
                        md5hashtable.Add(key, val);
                        //Console.WriteLine(line);
                        counter++;
                    }

                }
                file.Close();
                return (md5hashtable);
            }
        }

        public static void AutomateWord(RootObjects tobe, Hashtable file_list, string outputfilepath)
        {
            AutomateWordImpl(tobe, file_list, outputfilepath);


            // Clean up the unmanaged Word COM resources by forcing a garbage 
            // collection as soon as the calling function is off the stack (at 
            // which point these objects are no longer rooted).

            GC.Collect();
            GC.WaitForPendingFinalizers();
            // GC needs to be called twice in order to get the Finalizers called 
            // - the first time in, it simply makes a list of what is to be 
            // finalized, the second time in, it actually is finalizing. Only 
            // then will the object do its automatic ReleaseComObject.
            GC.Collect();
            GC.WaitForPendingFinalizers();
        }

        private static void AutomateWordImpl(RootObjects tobe, Hashtable keys, string outputfilepath)
        {
            object missing = Type.Missing;
            object oEndOfDoc = @"\endofdoc";    // A predefined bookmark 
            object notTrue = false;

            try
            {
                // Create an instance of Microsoft Excel and make it invisible.
                Word.Application oWord = new Word.Application();
                oWord.Visible = false;
                //Console.WriteLine("Word.Application is started");

                // Create a new Document and add it to document collection.
                Word.Document oDoc = oWord.Documents.Add(ref missing, ref missing,
                    ref missing, ref missing);

                foreach (string value in keys.Keys)
                {
                    RootObject result = tobe[value];
                    {
                        // Insert a paragraph.
                        //Console.WriteLine("Insert a paragraph");
                        string add;
                        if (string.Equals("1", result.response_code.ToString(), StringComparison.OrdinalIgnoreCase))
                        {
                            string Resource = "Resource: " + result.resource.ToString() + "\n";
                            string filepath = "File path: " + keys[value].ToString() + "\n";
                            string HTML = "Html permalink: " + result.permalink.ToString() + "\n";
                            string LastScan = "Last time a Scan was run : " + result.scan_date.ToString() +"\n" ;
                            string total = "Total: " + result.total.ToString() + "\n";
                            add = Resource + filepath + HTML + total + LastScan;
                        }
                        else
                        {
                            string Resource = "Resource: " + result.resource.ToString() + "\n";
                            string filepath = "File path: " + keys[value].ToString() + "\n";
                            string vmsg = " " + result.verbose_msg + "\n";
                            add = Resource +filepath + vmsg;
                        }

                        Word.Paragraph oPara = oDoc.Paragraphs.Add(ref missing);
                        oPara.Range.Text = add;
                        //oPara.Range.Text = HTML;
                        oPara.Range.Font.Bold = 0;
                        oPara.Range.Font.Size = 12;
                        oPara.Range.InsertParagraphAfter();
                        


                        // Insert a table.
                        if (string.Equals("1", result.response_code.ToString(), StringComparison.OrdinalIgnoreCase))
                        {
                            

                            //Console.WriteLine("Insert a table");
                            int total = Convert.ToInt32(result.total.ToString());
                            Word.Range oBookmarkRng = oDoc.Bookmarks.get_Item(ref oEndOfDoc).Range;
                            Word.Table oTable = oDoc.Tables.Add(oBookmarkRng, total, 5,
                                ref missing, ref missing);
                            oTable.Range.ParagraphFormat.SpaceAfter = 6;
                            Scans blah = result.scans;
                            //blah.keys
                            int count = 1;
                            oTable.Cell(count, 1).Range.Text = "Provider";
                            oTable.Cell(count, 2).Range.Text = "Detected";
                            oTable.Cell(count, 3).Range.Text = "Result File";
                            oTable.Cell(count, 4).Range.Text = "Last Update";
                            oTable.Cell(count, 5).Range.Text = "Version";
                            ++count;

                            foreach (string key in result.scans.Keys)
                            {
                                //foreach 
                                //Console.WriteLine(key);

                                oTable.Cell(count, 1).Range.Text = key.ToString();
                                oTable.Cell(count, 2).Range.Text = Convert.ToString(result.scans[key.ToString()].Detected);
                                oTable.Cell(count, 3).Range.Text = result.scans[key.ToString()].Result;
                                oTable.Cell(count, 4).Range.Text = result.scans[key.ToString()].Update;
                                oTable.Cell(count, 5).Range.Text = result.scans[key.ToString()].Version;

                                ++count;
                            }

                            // Change width of columns 1 & 2
                           // oTable.Columns[1].Width = oWord.InchesToPoints(2);
                           // oTable.Columns[2].Width = oWord.InchesToPoints(3);
                        }
                    }
                    oDoc.Words.Last.InsertBreak(ref missing);
                }
                // Save the document as a docx file and close it.
                Console.WriteLine("Save and close the document");

                object fileName = Path.GetDirectoryName(
                    Assembly.GetExecutingAssembly().Location) + "\\" + outputfilepath;
                object fileFormat = Word.WdSaveFormat.wdFormatXMLDocument;

                // Saves the document with a new name or format. 
                // Some of the arguments for this method correspond to 
                // the options in the Save As dialog box. 
                // For details,please refer to
                // :http://msdn.microsoft.com/en-us/library/microsoft.office.tools.word.document.saveas(VS.80).aspx
                oDoc.SaveAs(ref fileName, ref fileFormat, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing);
                ((Word._Document)oDoc).Close(ref missing, ref missing,
                    ref missing);

                // Quit the Word application.
                Console.WriteLine("Quit the Word application");
                ((Word._Application)oWord).Quit(ref notTrue, ref missing,
                    ref missing);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Solution2.AutomateWord throws the error: {0}",
                       ex.Message);
            }
        }

    }
}
